# -*- coding: utf-8 -*-
import pygame
import random
from sys import exit
import http.client
import json
import ssl
import threading
import time

class Bullet:
    def __init__(self):
        self.x = 0
        self.y = -1
        self.image = pygame.image.load('bullet.png').convert_alpha()
        self.active = False

    def move(self):
        if self.active:
            self.y -= 0.8
        if self.y < 0:
            self.active = False

    def restart(self):
        mouseX, mouseY = pygame.mouse.get_pos()
        self.x = mouseX - self.image.get_width() / 2
        self.y = mouseY - self.image.get_height() / 2
        self.active = True

class Enemy:
    def restart(self):
        self.x = random.randint(50, 400)
        self.y = random.randint(-200, -50)
        self.speed = random.random() + 0.1
        
    def __init__(self):
        self.restart()
        self.image = pygame.image.load('enemy.png').convert_alpha()

    def move(self):
        if self.y < 800:
            self.y += self.speed
        else:
            self.restart()

class Plane:
    def restart(self):
        self.x = 200
        self.y = 600
        
    def __init__(self):
        self.restart()
        self.image = pygame.image.load('plane.png').convert_alpha()

    def move(self):
        x, y = pygame.mouse.get_pos()
        x-= self.image.get_width() / 2
        y-= self.image.get_height() / 2
        self.x = x
        self.y = y

def checkHit(enemy, bullet):
    if (bullet.x > enemy.x and bullet.x < enemy.x + enemy.image.get_width()) and (
        bullet.y > enemy.y and bullet.y < enemy.y + enemy.image.get_height()
    ):
        enemy.restart()
        bullet.active = False
        #增加返回值
        return True
    return False

def checkCrash(enemy, plane):
    if (plane.x + 0.7*plane.image.get_width() > enemy.x) and (
        plane.x + 0.3*plane.image.get_width() < enemy.x + enemy.image.get_width()) and (
        plane.y + 0.7*plane.image.get_height() > enemy.y) and (
        plane.y + 0.3*plane.image.get_width() < enemy.y + enemy.image.get_height()
    ):
        return True
    return False

def req_api():
    global received_msg
    print('requesting api')
    topic = random.choice(['对关卡的说明', '对前方危险的提醒', '对当前飞行状态的反馈', '飞行驾驶注意事项', '新装备的武器说明', '敌机战力的判断'])

    # 创建一个忽略证书验证的 SSL 上下文
    context = ssl._create_unverified_context()
    conn = http.client.HTTPSConnection("cephalon.cloud", context=context)

    payload = json.dumps({
        "model": "Llama-3.1-70B-Instruct",
        "messages": [
            {
                "role": "system",
                "content": "You are an NPC in a game."
            },
            {
                "role": "user",
                "content": f'场景是《飞机大战》游戏，你作为主角的领航员NPC，定位是一名喜欢吐槽的傲娇娘，随机生成一句话。内容与游戏相关，主题是{topic}。不要回答如“好的”之类的内容，直接输出你要生成的话。注意对话要尽可能搞笑、有梗。'
            }
        ],
    })

    headers = {
        'Authorization': "Bearer 这里替换为你的令牌key",
        'Content-Type': 'application/json'
    }

    try:
        conn.request("POST", "https://cephalon.cloud/user-center/v1/model/chat/completions", payload, headers)
        res = conn.getresponse()
        t = res.read().decode("utf-8")
        received_msg = json.loads(t)['choices'][0]['message']['content'].strip('"“”\'')
    except:
        print('request api faild')
        received_msg = ''
        global interval_msg, sending_msg, start_time
        interval_msg = random.randint(100, 500)
        sending_msg = False
        start_time = None
        print(t)

def send_msg():
    threading.Thread(target=req_api).start()
    global sending_msg
    sending_msg = True

def draw_text(surface, text, color, rect, font, line_spacing=5):
    """在给定矩形内绘制多行文本"""
    words = list(text)  # 分割文本
    space_width, _ = font.size(' ')  # 获取空格宽度

    x, y = rect.topleft
    max_width, max_height = rect.size

    lines = []
    current_line = ""
    for word in words:
        # 加上单词后，测试行宽是否超出最大宽度
        test_line = current_line + word
        line_width, _ = font.size(test_line)
        if line_width <= max_width:
            current_line = test_line  # 在当前行添加单词
        else:
            lines.append(current_line)  # 超出宽度，将当前行存储
            current_line = word       # 新行起始

    lines.append(current_line)  # 最后一行

    for line in lines:
        # if y + font.get_height() > rect.bottom:
        #     break  # 如果超过矩形高度，则停止绘制
        text_surface = font.render(line, True, color)
        surface.blit(text_surface, (x, y))
        y += font.get_height() + line_spacing  # 更新y位置


def draw_popup(x, y, text):
    """绘制弹窗"""
    # 弹窗背景
    ht = max(int(len(text) / 15) + 2, 4)
    POPUP_RECT = (x, y, popup_width, (font.get_height()+5) * ht)
    pygame.draw.rect(screen, WHITE, POPUP_RECT)
    pygame.draw.rect(screen, BLACK, POPUP_RECT, 2)

    # 绘制图标
    screen.blit(icon, (x + 10, y + 10))

    # 绘制文本
    TEXT_RECT = pygame.Rect(x + 84, y + 10, popup_width - 90, popup_height)
    draw_text(screen, text, BLACK, TEXT_RECT, font)


pygame.init()
screen = pygame.display.set_mode((450, 800), 0, 32)
pygame.display.set_caption("Hello, World!")
background = pygame.image.load('back.jpg').convert()
plane = Plane()
bullets = []
for i in range(5):
    bullets.append(Bullet())
count_b = len(bullets)
index_b = 0
interval_b = 0
enemies = []
for i in range(5):
    enemies.append(Enemy())
gameover = False
#分数
score = 0
#用以显示文字的font变量
# font = pygame.font.Font(None, 32)
font_path = "zhaozi.ttf"  # 微软雅黑的字体文件路径
font_size = 14
font = pygame.font.Font(font_path, font_size)
h = 0

interval_msg = 300
sending_msg = False
received_msg = ''

# 弹窗属性
popup_width, popup_height = 300, 100
popup_x = 450  # 起始位置在屏幕右侧外
popup_y = 50
popup_speed = 20  # 控制滑入速度
show_duration = 5  # 弹窗显示的时间（秒）
# 控制变量
popup_visible = True
start_time = None
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (180, 180, 180)
icon = pygame.image.load('navigator.jpg')

while True:
    h = (h + 0.1) % 800 - 800
    interval_msg -= 1
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        #判断在gameover状态下点击了鼠标
        if gameover and event.type == pygame.MOUSEBUTTONUP:
            #重置游戏
            plane.restart()
            for e in enemies:
                e.restart()
            for b in bullets:
                b.active = False
            score = 0
            gameover = False
    screen.blit(background, (0,h))

    if interval_msg <= 0 and not sending_msg:
        send_msg()

    if not gameover:
        interval_b -= 1
        if interval_b < 0:
            bullets[index_b].restart()
            interval_b = 200
            index_b = (index_b + 1) % count_b
        for b in bullets:
            if b.active:
                for e in enemies:
                    #击中敌机后，分数加100
                    if checkHit(e, b):
                        score += 100
                b.move()
                screen.blit(b.image, (b.x, b.y))
        for e in enemies:
            if checkCrash(e, plane):
                gameover = True
            e.move()
            screen.blit(e.image, (e.x, e.y))
        plane.move()
        screen.blit(plane.image, (plane.x, plane.y))
        #在屏幕左上角显示分数
        text = font.render("Socre: %d" % score, 1, (0, 255, 255))
        screen.blit(text, (0, 0))
    else:
        #在屏幕中央显示分数
        text = font.render("Socre: %d" % score, 1, (0, 255, 255))
        screen.blit(text, (190, 400))
        pass

    if received_msg:
        # print(received_msg)
        # 控制弹窗滑入
        if popup_x > 450 - popup_width - 20:  # 弹窗滑动到目标位置
            popup_x -= popup_speed
        else:
            if start_time is None:  # 记录弹窗完全显示的时间
                start_time = time.time()

        # 显示弹窗
        draw_popup(popup_x, popup_y, received_msg)

        # 检查弹窗显示时间
        if start_time and time.time() - start_time > show_duration:
            # popup_visible = False  # 隐藏弹窗
            received_msg = ''
            interval_msg = random.randint(100, 500)
            sending_msg = False
            start_time = None

    pygame.display.update()

